﻿using System;
using System.Web;
using System.Collections;
using LRJ.Profile;
using LRJ.Text;
using CookComputing.XmlRpc;

namespace LRJ.Snipplr
{

    #region APIServiceModels
    /// <summary>
    /// C# structs returned by XML-RPC calls
    /// </summary>   
    public struct SnippetModel
    {
        public string id;
        public string user_id;
        public string username;
        public string title;
        public string language;
        public string comment;
        public string created;      
        public string source;
        public string snipplr_url; //url to view snippet
        public string tags;        //tags (space delimited list of the snippet’s tags)
    }
    public struct SnippetListModel 
    {
        public string title, id;
        public SnippetUpdate updated;
        public bool favorite;
    }
    public struct SnippetLangList
    { 
        public string[] urlname;
        public string[] pretty_name;
    }
    public struct SnippetUpdate
    {
        [XmlRpcMember("datetime")]
        public DateTime datetime;
        [XmlRpcMember("timezone")]
        public string TimeZone;
    }
    

    #endregion
    #region APIServiceExceptions
    public enum APIServiceStatusCode
    {
        Ready = -1,
        Success,
        ListNotFound,
        IDNotFound,
        BadApiKey,
        MethodNotFound
    }
    abstract class APIServiceFaultException : XmlRpcFaultException
    {
        private APIServiceStatusCode _errorStatus;

        public APIServiceStatusCode ErrorStatus { get { return (APIServiceStatusCode)this.FaultCode; } }
        APIServiceFaultException() : base(0, "message") { } 
    }

    
    #endregion

    #region APIServiceMethods
    /// <summary>
    /// Converts XML-RPC responses into Snipplr API ServiceModels
    /// </summary>
    [XmlRpcUrl("http://snipplr.com/xml-rpc.php")]
    public interface IApiProxy : IXmlRpcProxy
    {
        /// <summary>
        /// Returns an XML formatted list of snippets matching the specified criteria.
        /// </summary>
        /// <param name="api_key">Required. The API key of the Snipplr user. 
        /// Snipplr returns all of this user’s snippets. An error message 
        /// will be returned if the API key is invalid.</param>
        /// <param name="tags">Optional. A space delimited list of tags (keywords)
        /// to filter the results by. Snipplr returns snippets which contain at 
        /// least one of the keywords in the snippet’s title or that match one 
        /// of the snippet’s tags.</param>
        /// <param name="sort">Optional. Can be one of these three values: 
        /// “title”, “date”, “random”.</param>
        /// <param name="limit">Optional. The number of snippets to return.</param>
        /// <returns>Returns an XML formatted list of snippets matching the specified criteria.
        /// Note: snippet.list only returns snippets owned by the user or marked as favorites
        /// of the user. It does not search all of the snippets on Snipplr.
        /// <value>object[4]</value>
        /// <list type="numbered">
        ///     <listheader>
        ///         <term>Key</term><description>Type</description>
        ///     </listheader>
        ///     <item>
        ///         <term>title</term><description>string</description>
        ///     </item>
        ///     <item>
        ///         <term>uptated</term><description>struct</description>
        ///     </item>
        ///     <item>
        ///         <term>id</term><description>string</description>
        ///     </item>
        ///     <item>
        ///         <term>favorite</term><description>bool</description>
        ///     </item>
        /// </list>
        /// </returns>
        [XmlRpcMethod("snippet.list")]
        SnippetListModel[] ListSnippets(string api_key, string tags, string sort, int limit);

        /// <summary>
        /// returns a snippet’s details. Takes one parameter.
        /// <seealso cref="SnippetModel"/>
        /// </summary>
        /// <param name="snippet_id">Required. The ID of the snippet to fetch. 
        /// An error message will be returned if the ID is invalid.</param>
        /// <returns>
        /// 1. id
        /// 2. user_id
        /// 3. username
        /// 4. title
        /// 5. language
        /// 6. comment
        /// 7. created (datetime when snippet was created)
        /// 8. source
        /// 9. snipplr_url (url to view snippet)
        /// 10. tags (space delimited list of the snippet’s tags)
        /// </returns>
        [XmlRpcMethod("snippet.get")]
        SnippetModel GetSnippet(string snippet_id);

        /// <summary>
        /// stores a new snippet into Snipplr.
        /// </summary>
        /// <param name="api_key">Required. The API key of the Snipplr user to which 
        /// the snippet will belong. An error message will be returned if the API 
        /// key is invalid.</param>
        /// <param name="title">Required. The title of the snippet.</param>
        /// <param name="code">Required. The snippet’s source code.</param>
        /// <param name="tags">Optional. A space delimited list of keywords to tag 
        /// the snippet with.</param>
        /// <param name="language">Optional. The language to mark the snippet as. 
        /// Use the language name found in Snipplr’s URLs. For example, “javascript” or “c-plus-plus”.</param>
        [XmlRpcMethod("snippet.post")]
        int PostSnippet(string api_key, string title, string code, string tags, string language);

        /// <summary>
        /// deletes a snippet from your Snipplr account. Returns 1 on success, 0 if 
        /// the snippet could not be deleted.
        /// </summary>
        /// <param name="api_key">Required. The API key of the Snipplr user that
        /// created the snippet you are deleting. An error message will be returned 
        /// if the API key is invalid.</param>
        /// <param name="snippet_id">Required. The ID of the snippet you are deleting.</param>
        [XmlRpcMethod("snippet.delete")]
        int DeleteSnippet(string api_key, string snippet_id);

        /// <summary>
        /// Validates a user’s API key.
        /// </summary>
        /// <param name="api_key">The API key to validate.</param>
        /// <returns>1 if the key is valid. 0 if not valid.</returns>
        [XmlRpcMethod("user.checkkey")]
        int CheckApiKey(string api_key);

        /// <summary>
        /// returns a list of supported languages in Snipplr. 
        /// </summary>
        /// <returns>It returns their urlname and pretty name. The urlname is the value 
        /// you pass into the snippet.post method. The pretty name is a nicely formatted 
        /// version of urlname. It’s just there for your reference.
        /// <para>urlname</para>
        /// <para>pretty name</para>
        /// </returns>
        [XmlRpcMethod("languages.list")]
        SnippetLangList[] ListLanguages();
    }
    public static class SnipplrProxy
    {
        public static IApiProxy Create()
        {
            IApiProxy proxy;
            try
            {
                return XmlRpcProxyGen.Create<IApiProxy>();
            }
            catch (CookComputing.XmlRpc.XmlRpcFaultException apiEx)
            {
                throw (APIServiceFaultException)apiEx;
            }
            return proxy;
        }
        public static bool HasView(string snippetId)
        {
            bool _hasView = false;
            try 
	        {	        
        	    IApiProxy proxy = XmlRpcProxyGen.Create<IApiProxy>();
                proxy.GetSnippet(snippetId);
                _hasView = true;
	        }
	        catch (CookComputing.XmlRpc.XmlRpcFaultException )
	        {
        	    _hasView = false;
	        }
            return _hasView;
        }
    }
    #endregion

}
